package com.myapplication;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.OverScroller;
import android.widget.ScrollView;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class DiscoverScrollView extends ScrollView {
    private static final String TAG = DiscoverScrollView.class.getSimpleName();
    private boolean mInterceptTouchEvent = true;
    private OnScrollListener mListener;

    public DiscoverScrollView(Context context) {
        this(context, null);
    }

    public DiscoverScrollView(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.scrollViewStyle);
    }

    public DiscoverScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void finish() {
        smoothScrollBy(0, 0);
        smoothScrollBy(0, 0);

        try {
            Field scroller = ScrollView.class.getDeclaredField("mScroller");
            scroller.setAccessible(true);

            OverScroller overScroller = (OverScroller) scroller.get(this);
            Field flingStrictSpan = ScrollView.class.getDeclaredField("mFlingStrictSpan");
            flingStrictSpan.setAccessible(true);

            Object obj = flingStrictSpan.get(this);
            if (!overScroller.isFinished()) {
                overScroller.abortAnimation();
                if (obj != null) {
                    Method method = obj.getClass().getDeclaredMethod("finish", new Class[0]);
                    method.setAccessible(true);
                    method.invoke(obj, new Object[0]);
                    flingStrictSpan.set(obj, null);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setInterceptTouchEvent(boolean isIntercept) {
        this.mInterceptTouchEvent = isIntercept;
        if (!isIntercept) {
            finish();
        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        boolean ret;
        if (!mInterceptTouchEvent) {
            Log.i(TAG, "DiscoverScrollView onInterceptTouchEvent mInterceptTouchEvent false");
            ret = false;
        } else {
            ret = super.onInterceptTouchEvent(ev);
        }
        Log.i(TAG, "DiscoverScrollView onInterceptTouchEvent[" + ev.getAction() + "]=" + ret);
        return ret;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int mask = ev.getActionMasked();

        boolean ret;
        if (!mInterceptTouchEvent && ((mask == MotionEvent.ACTION_MOVE) || (mask == MotionEvent.ACTION_UP))) {
            Log.i(TAG, "DiscoverScrollView onTouchEvent[" + ev.getAction() + "]=false");
            ret = false;
        } else {
            ret = super.onTouchEvent(ev);
        }
        Log.i(TAG, "DiscoverScrollView onTouchEvent[" + ev.getAction() + "]=" + ret);
        return ret;
    }

    @Override
    public void requestChildFocus(View child, View focused) {
        super.requestChildFocus(child, focused);
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (mListener != null) {
            mListener.onScroll(l, t);
        }
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        boolean ret = super.dispatchTouchEvent(ev);
        Log.i(TAG, "DiscoverScrollView dispatchTouchEvent[" + ev.getAction() + "]=" + ret);
        return ret;
    }

    public void setScrollListener(OnScrollListener listener) {
        mListener = listener;
    }

    public interface OnScrollListener {
        void onScroll(int scrollX, int scrollY);
    }

    public interface OnScrollOverMaxDistanceListener {
        void onScrollOverDistance(boolean isOver);
    }
}
